/********************************************************************************************************
 * @file	whitelist_stack.h
 *
 * @brief	This is the header file for BLE SDK
 *
 * @author	BLE GROUP
 * @date	2020.06
 *
 * @par     Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
 *          All rights reserved.
 *
 *          Redistribution and use in source and binary forms, with or without
 *          modification, are permitted provided that the following conditions are met:
 *
 *              1. Redistributions of source code must retain the above copyright
 *              notice, this list of conditions and the following disclaimer.
 *
 *              2. Unless for usage inside a TELINK integrated circuit, redistributions
 *              in binary form must reproduce the above copyright notice, this list of
 *              conditions and the following disclaimer in the documentation and/or other
 *              materials provided with the distribution.
 *
 *              3. Neither the name of TELINK, nor the names of its contributors may be
 *              used to endorse or promote products derived from this software without
 *              specific prior written permission.
 *
 *              4. This software, with or without modification, must only be used with a
 *              TELINK integrated circuit. All other usages are subject to written permission
 *              from TELINK and different commercial license may apply.
 *
 *              5. Licensee shall be solely responsible for any claim to the extent arising out of or
 *              relating to such deletion(s), modification(s) or alteration(s).
 *
 *          THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *          ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *          WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *          DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
 *          DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *          (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *          LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *          ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *          (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *          SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *******************************************************************************************************/
#ifndef STACK_BLE_WHITELIST_STACK_H_
#define STACK_BLE_WHITELIST_STACK_H_




/******************************* whitelist start ******************************************************************/
#if LL_WHITELIST_OPTIMIZE_EN
	#define  		MAX_WHITE_LIST_SIZE    				1
#else
	#define  		MAX_WHITE_LIST_SIZE    				4
#endif

typedef u8 irk_key_t[16];

typedef struct {
	u8 type;
	u8 address[BLE_ADDR_LEN];
	u8 reserved;
} wl_addr_t;

typedef struct {
	wl_addr_t  wl_addr_tbl[MAX_WHITE_LIST_SIZE];
	u8 	wl_addr_tbl_index;
	u8 	wl_irk_tbl_index;
} ll_whiteListTbl_t;


typedef struct {
	u8 type;
	u8 address[BLE_ADDR_LEN];
	u8 reserved;
	u8 irk[16];
} rl_addr_t;

extern	ll_whiteListTbl_t		ll_whiteList_tbl;



u8				   *blt_ll_searchAddrInWhiteListTbl(u8 type, u8 *addr);
bool				smp_quickResolvPrivateAddr(u8 *key, u8 *addr);

/******************************* whitelist end  ******************************************************************/




/******************************* resolvlist start ******************************************************************/
#if LL_WHITELIST_OPTIMIZE_EN
	#define			MAX_RESOLVING_LIST_SIZE				1 //New RL NUM
	#define 		MAX_WHITE_IRK_LIST_SIZE          	1 //Old RL NUM used, remove latter TODO:
#else
	#define			MAX_RESOLVING_LIST_SIZE				2 //New RL NUM
	#define 		MAX_WHITE_IRK_LIST_SIZE          	2 //Old RL NUM used, remove latter TODO:
#endif

//Privacy mode define
#define 		PRIVACY_NETWORK_MODE             	0
#define 		PRIVACY_DEVICE_MODE              	1


typedef struct {
    u8 rlPrivMode;	 			//Privacy network(0) or privacy device(1)
    u8 rlIdAddrType; 			//Public address (0) or random address (1)
    u8 rlIdAddr[BLE_ADDR_LEN]; 	//The Identity Address is stored in little endian format

    u8 rlHasLocalRpa;
    u8 rsvd0;
    u8 rlLocalRpa[BLE_ADDR_LEN];//The local rpa is stored in little endian format

    u8 rlHasPeerRpa;
    u8 rsvd1;
    u8 rlPeerRpa[BLE_ADDR_LEN]; //The local rpa is stored in little endian format.

    u8 rlPeerIrk[16]; 			//The IRKs are stored in little endian format
    u8 rlLocalIrk[16];          //The IRKs are stored in little endian format
}ll_resolv_list_t;

typedef struct {
	u8  rpaTmrEn;   	 //1: rpa tmr start; 0: rpa tmr stop
	u8  rsvd[3];         //used align

	u16 rpaTimeoutXs;    //belong to [0x0001, 0x0E10], unit: 1s
	u16 rpaTmrCnt1sUnit; //design a 1s timer, accumulator unit 1s, 2^32/16us => 268.435456s

	u32 rpaTmr1sChkTick; //accumulate judgment ticks per second
}ll_rpaTmrCtrl_t;

typedef struct {
	rl_addr_t	tbl[MAX_WHITE_IRK_LIST_SIZE];
	u8 			idx;
	u8			en;
} ll_ResolvingListTbl_t; //Old RPA version, remove latter TODO:

typedef struct {
    u8 	rlSize;
    u8 	rlCnt;
    u16 addrRlEn;	//addr res enabled

    u16 rpaTmrEn;   //1: rpa tmr start; 0: rpa tmr stop
    u16 rpaTmo;		//0x0001 to 0x0E10, unit: 1s

    ll_rpaTmrCtrl_t  rpaTmoCtrl;

    ll_resolv_list_t rlList[MAX_RESOLVING_LIST_SIZE];

}ll_ResolvingListTbl_v2_t; //New RPA version

extern	ll_ResolvingListTbl_t		ll_resolvingList_tbl;
extern	ll_ResolvingListTbl_v2_t	ll_resolvingList_v2_tbl;


int					blt_ll_resolvPeerRpaResolvedAny(u8* rpa);
void				blt_ll_resolvGetRpaByRlEntry(ll_resolv_list_t* rl, u8* addr, u8 local);
void				blt_ll_resolvSetPeerRpaByIdx(u8 idx, u8 *rpa);
void				blt_ll_resolvSetLocalRpaByIdx(u8 idx, u8 *rpa);
bool				blt_ll_resolvGetRpaByAddr(u8* peerIdAddr, u8 peerIdAddrType, u8* rpa, u8 local);
bool				blt_ll_resolvIsAddrResolved(u8* irk, u8* rpa);
bool				blt_ll_resolvIsAddrRlEnabled(void);
bool 				blt_ll_resolvIrkIsNonzero(u8 *irk);
void				blt_ll_resolvGetPrand(u8* prand);
void 				blt_ll_resolvCalcAh(u8 irk[16], u8 r[3], u8 out[3]);
bool    			blt_ll_resolvChgIsAllowed(void);
void				blt_ll_resolvGenRpa(ll_resolv_list_t *rl, u8 local);
void				blt_ll_resolvRpaTmrCb(void);
int 				blt_ll_resolvRpaTmoLoopEvt (void);
int 				blt_ll_resolvIsAddrOnRl(u8 *addr, u8 addrType);
ll_resolv_list_t* 	blt_ll_resolvFindRlEntry(u8* addr, u8 addrType);
unsigned short 		blt_ll_resolvGetRpaTmo(void);

u8				   *ll_searchAddrInResolvingListTbl(u8 *addr);  //addr must be RPA
u8				   *ll_searchAddr_in_WhiteList_and_ResolvingList(u8 type, u8 *addr);

/******************************* resolvlist end  ******************************************************************/


#endif /* WHITELIST_STACK_H_ */
